/**
 * Created by xiebang
 * Description
 * User:小谢
 * Date:2021-09-10
 * Time:19:02
 */
class Animal{
    public String name;
    public int age;
    public Animal(String name){
        eat();
        this.name = name;
    }
    public void eat(){
        System.out.println(this.name + "正在吃饭！(Animal)");
    }

    public void dark(){
        System.out.println(this.name + "叫！");
    }
}

class Cat extends Animal{
    public Cat(String name) {
        super(name);
    }

    public void upTree(){
        System.out.println(this.name + "上树");
    }
}

//重写 override
/*
1、方法名相同
2、方法的参数相同
3、方法的返回值相同
 */
//重载 overload
/*
1.方法名相同
2、方法的参数不同（数据的个数和类型）
3、方法的返回值不做要求
 */
class Dog extends Animal{

    public Dog(String name) {
        super(name);//构造方法没有被继承
    }
    @Override//注解的作用是当没发生重写时程序会报错。
    public void eat(){
        System.out.println(this.name + "正在吃饭！(dog)");//相当于重写
    }

}

class  Bird extends Animal {

    public Bird(String name) {
        super(name);
    }
    public String Wing;
    public void fly() {
        System.out.println(this.name + "正在飞");
    }
}
/*
理解多态：
 */
public class TestDemo {
    public static void main(String[] args) {
       Dog dog = new Dog("小虎！");

    }
    public static void main5(String[] args) {
        Animal animal = new Bird("圆圆");
        animal.eat();
        System.out.println("========");
        Bird bird = (Bird) animal;
        bird.fly();
        System.out.println("========");

        Animal animal1 = new Dog("小虎！");
        if (animal1 instanceof Bird) {
            Bird bird1 = (Bird) animal1;
            bird.fly();
        }
    }

    /*
    向下转型：把父类的对象赋值给子类的引用
     */
    public static void main4(String[] args) {
//        Animal animal = new Animal("哈哈！");
//        Dog dog = (Dog) animal;
//        dog.eat();
//
        //向下转型一定会发生向上转型
        Animal animal = new Dog("小虎");
        Dog dog = (Dog) animal;
        dog.eat();
    }
    /*
    通过父类引用调用方法或者成员变量的时候只能调用父类自己的特有方法和成员变量
     */
    public static void main3(String[] args) {
//        Animal animal = new Animal("动物");
//        animal.eat();
        Animal animal1 = new Dog("小虎");
        animal1.eat();//调用不到dog里面的eat方法

        //（运行时绑定）动态绑定 ： 1.向上转型
        //2、通过父类引用 来调用子类个父类同名覆盖的方法
        //编译时调用父类的方法，运行时调用子类的方法

        //重写的注意事项
        /*
        方法不能被final修饰
        密封方法：当前方法不能被重写  final

       2、子类的的访问修饰限定符权限一定要大于等于父类的权限，但父类不能是private
       3、方法不能是static
       4、
         */
    }
    public static Dog func3(){
        Dog dog = new Dog("小虎！");
        return dog;
    }
    public static Animal func2(){

        //return new Dog("小虎！");
        Dog dog = new Dog("小虎");
        return dog;
    }
    public static void func1(Animal animal1){

    }
    public static void main2(String[] args) {
//        Animal animal = new Animal("动物");
//
//        Dog dog = new Dog("小虎");
//        animal = dog;
        //向上转型 ：子类的对象赋值给父类的引用
        Animal animal = new Dog("小虎");

        //向上转型发生的时机
        //1.直接赋值
        //2.方法传参
        //3、方法返回
        Dog dog = new Dog("mimi");
        //向上转型
        func1(animal);
        func1(dog);

        Animal animal2 = func3();
    }
    public static void main1(String[] args) {
        Dog dog = new Dog("mimi");
        dog.eat();
    }

}
